package com.aspect;

import com.annotation.LoginRequired;
import com.utils.TokenUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;

/**
 * 权限认证切面，用于拦截使用 @LoginRequired 注解的方法
 */
@Aspect
@Component
public class LoginAspect {
    @Before("@annotation(com.annotation.LoginRequired) || @within(com.annotation.LoginRequired)")
    public void before(JoinPoint point) throws Throwable {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        // 检查方法上是否有 @LoginRequired 注解
        LoginRequired methodAnnotation = AnnotationUtils.findAnnotation(method, LoginRequired.class);
        if (methodAnnotation == null) {
            // 方法上没有注解，检查类上是否有注解
            methodAnnotation = AnnotationUtils.findAnnotation(point.getTarget().getClass(), LoginRequired.class);
        }

        // 如果没有注解，直接返回
        if (methodAnnotation == null) {
            return;
        }

        // 获取当前请求属性
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            // 非Web环境下直接放行或抛出异常，根据需求决定
            throw new RuntimeException("无法获取请求上下文，非Web环境不支持权限验证");
        }

        // 检查是否为Servlet请求
        if (requestAttributes instanceof ServletRequestAttributes) {
            ServletRequestAttributes servletAttributes = (ServletRequestAttributes) requestAttributes;
            HttpServletRequest request = servletAttributes.getRequest();

            // 获取请求头中的Token
            String token = request.getHeader("Authorization");

            // 验证Token
            if (!TokenUtils.validateToken(token)) {
                throw new RuntimeException("未登录或Token已过期，请重新登录");
            }
        } else {
            // 非Servlet请求，根据需求处理
            throw new RuntimeException("不支持的请求类型，仅支持Servlet请求");
        }
    }
}
